package org.infodavid.common.persistence;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;

import junit.framework.Assert;

import org.junit.Test;

import org.infodavid.common.dto.ITemplateVersionListItem;
import org.infodavid.common.impl.model.criteria.TemplateVersionCriteriaImpl;
import org.infodavid.common.model.ITemplateVersion;
import org.infodavid.common.model.TemplateVersionTest;
import org.infodavid.common.model.criteria.ITemplateVersionCriteria;

/**
 * The Class TemplateDataServiceTest.
 */
@SuppressWarnings({
    "null", "boxing"
})
public class TemplateVersionDataServiceTest extends
    AbstractDataServiceTest<ITemplateVersionListItem,ITemplateVersion,Long> {

	/**
	 * The Constructor.
	 */
	public TemplateVersionDataServiceTest() {
		super(new TemplateVersionTest(), TemplateVersionDataService.getInstance());
	}

	/*
	 * See super class or interface. (non-Javadoc)
	 * @see
	 * org.infodavid.common.persistence.AbstractDataServiceTest#modify(org.infodavid.common.model.IDataObject
	 * )
	 */
	@Override
	public void modify(final ITemplateVersion item) {
		item.setComment(item.getComment() + "modif" + RAND.nextInt(1000));
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindByCriteria() throws Exception {
		final List<ITemplateVersionListItem> results = new ArrayList<ITemplateVersionListItem>();
		final ITemplateVersionCriteria criteria = new TemplateVersionCriteriaImpl();
		final long count =
		    ((TemplateVersionDataService)getService()).find(getSession(), results, criteria);

		// System.out.println(results);

		Assert.assertNotNull("Result is null", results);
		Assert.assertEquals("Not all data has been found", ITEMS_TO_INSERT, results.size());
		Assert.assertEquals("Not all data has been found", ITEMS_TO_INSERT, count);
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindByCriteriaUsingAllCriterions() throws Exception {
		final Collection<ITemplateVersion> inserted = getTestData();
		final ITemplateVersion version = inserted.iterator().next();
		final List<ITemplateVersionListItem> results = new ArrayList<ITemplateVersionListItem>();
		final ITemplateVersionCriteria criteria = new TemplateVersionCriteriaImpl();

		criteria.setNamePattern(version.getName());
		criteria.setRevision(version.getRevision());
		criteria.setTemplateKey(version.getTemplate().getKey());

		final long count =
		    ((TemplateVersionDataService)getService()).find(getSession(), results, criteria);

		// System.out.println(results);

		Assert.assertNotNull("Result is null", results);
		Assert.assertEquals("Not all data has been found", 1, results.size());
		Assert.assertEquals("Not all data has been found", results.size(), count);
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindByCriteriaUsingNameNoDataFound() throws Exception {
		final List<ITemplateVersionListItem> results = new ArrayList<ITemplateVersionListItem>();
		final ITemplateVersionCriteria criteria = new TemplateVersionCriteriaImpl();

		criteria.setNamePattern("NoData");

		final long count =
		    ((TemplateVersionDataService)getService()).find(getSession(), results, criteria);

		// System.out.println(results);

		Assert.assertNotNull("Result is null", results);
		Assert.assertEquals("Not all data has been found", 0, results.size());
		Assert.assertEquals("Not all data has been found", 0, count);
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindByCriteriaUsingTemplateEqual() throws Exception {
		final Collection<ITemplateVersion> inserted = getTestData();
		final List<ITemplateVersionListItem> results = new ArrayList<ITemplateVersionListItem>();
		final ITemplateVersionCriteria criteria = new TemplateVersionCriteriaImpl();

		criteria.setTemplateKey(inserted.iterator().next().getTemplate().getKey());

		final long count =
		    ((TemplateVersionDataService)getService()).find(getSession(), results, criteria);

		// System.out.println(results);

		Assert.assertNotNull("Result is null", results);
		Assert.assertEquals("Not all data has been found", 1, results.size());
		Assert.assertEquals("Not all data has been found", results.size(), count);
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindByCriteriaUsingRevisionEqual() throws Exception {
		final Collection<ITemplateVersion> inserted = getTestData();
		final List<ITemplateVersionListItem> results = new ArrayList<ITemplateVersionListItem>();
		final ITemplateVersionCriteria criteria = new TemplateVersionCriteriaImpl();

		criteria.setRevision(inserted.iterator().next().getRevision());

		final long count =
		    ((TemplateVersionDataService)getService()).find(getSession(), results, criteria);

		// System.out.println(results);

		Assert.assertNotNull("Result is null", results);
		Assert.assertEquals("Not all data has been found", 1, results.size());
		Assert.assertEquals("Not all data has been found", results.size(), count);
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindByCriteriaUsingNameEqual() throws Exception {
		final Collection<ITemplateVersion> inserted = getTestData();
		final List<ITemplateVersionListItem> results = new ArrayList<ITemplateVersionListItem>();
		final ITemplateVersionCriteria criteria = new TemplateVersionCriteriaImpl();

		criteria.setNamePattern(inserted.iterator().next().getName());

		final long count =
		    ((TemplateVersionDataService)getService()).find(getSession(), results, criteria);

		// System.out.println(results);

		Assert.assertNotNull("Result is null", results);
		Assert.assertEquals("Not all data has been found", 1, results.size());
		Assert.assertEquals("Not all data has been found", results.size(), count);
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindByCriteriaUsingNameLike() throws Exception {
		final List<ITemplateVersionListItem> results = new ArrayList<ITemplateVersionListItem>();
		final ITemplateVersionCriteria criteria = new TemplateVersionCriteriaImpl();

		criteria.setNamePattern("item%");

		final long count =
		    ((TemplateVersionDataService)getService()).find(getSession(), results, criteria);

		// System.out.println(results);

		Assert.assertNotNull("Result is null", results);
		Assert.assertEquals("Not all data has been found", ITEMS_TO_INSERT, results.size());
		Assert.assertEquals("Not all data has been found", ITEMS_TO_INSERT, count);
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindByCriteriaUsingNullCollection() throws Exception {
		final ITemplateVersionCriteria criteria = new TemplateVersionCriteriaImpl();
		Exception exception = null;

		try {
			((TemplateVersionDataService)getService()).find(getSession(), null, criteria);
		}
		catch (final Exception e) {
			exception = e;
			e.printStackTrace();
		}

		Assert.assertNotNull("No exception thrown", exception);
		Assert.assertEquals("Wrong exception thrown", IllegalArgumentException.class,
		    exception.getClass());
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindByCriteriaUsingNullCriteria() throws Exception {
		final List<ITemplateVersionListItem> results = new ArrayList<ITemplateVersionListItem>();
		final long count =
		    ((TemplateVersionDataService)getService()).find(getSession(), results,
		        (ITemplateVersionCriteria)null);

		// System.out.println(results);

		Assert.assertNotNull("Result is null", results);
		Assert.assertEquals("Not all data has been found", ITEMS_TO_INSERT, results.size());
		Assert.assertEquals("Not all data has been found", ITEMS_TO_INSERT, count);
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindByCriteriaUsingPage() throws Exception {
		final List<ITemplateVersionListItem> results = new ArrayList<ITemplateVersionListItem>();
		final ITemplateVersionCriteria criteria = new TemplateVersionCriteriaImpl();

		criteria.setPageStart(Long.valueOf(0));
		criteria.setPageSize(Integer.valueOf(5));

		final long count =
		    ((TemplateVersionDataService)getService()).find(getSession(), results, criteria);

		// System.out.println(results);

		Assert.assertNotNull("Result is null", results);
		Assert.assertEquals("Not all data has been found", criteria.getPageSize().intValue(),
		    results.size());
		Assert.assertEquals("Not all data has been found", ITEMS_TO_INSERT, count);
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindLastByName() throws Exception {
		final List<ITemplateVersion> inserted = getTestData();
		final ITemplateVersion version = inserted.listIterator(inserted.size()).previous();
		final ITemplateVersion result =
		    ((TemplateVersionDataService)getService()).findLastVersionByName(getSession(),
		        version.getName(), version.getTemplate().getLanguage());

		Assert.assertNotNull("Result is null", result);
		Assert.assertEquals("Wrong data found", version.getName(), result.getName());
		Assert.assertEquals("Wrong data found", version.getKey(), result.getKey());
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindLastByNameUsingNull() throws Exception {
		Exception exception = null;

		try {
			((TemplateVersionDataService)getService()).findLastVersionByName(getSession(), null,
			    Locale.getDefault());
		}
		catch (final Exception e) {
			exception = e;
			e.printStackTrace();
		}

		Assert.assertNotNull("No exception thrown", exception);
		Assert.assertEquals("Wrong exception thrown", IllegalArgumentException.class,
		    exception.getClass());
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindLastRevision() throws Exception {
		final List<ITemplateVersion> inserted = getTestData();
		final ITemplateVersion version = inserted.get(inserted.size() - 1);
		final Integer result =
		    ((TemplateVersionDataService)getService()).findLastRevision(getSession(), version
		        .getTemplate().getKey());

		Assert.assertNotNull("Result is null", result);
		Assert.assertEquals("Wrong data found", version.getRevision(), result.intValue());
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindLastRevisionUsingNull() throws Exception {
		Exception exception = null;

		try {
			((TemplateVersionDataService)getService()).findLastRevision(getSession(), null);
		}
		catch (final Exception e) {
			exception = e;
			e.printStackTrace();
		}

		Assert.assertNotNull("Exception thrown", exception);
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindLastVersion() throws Exception {
		final List<ITemplateVersion> inserted = getTestData();
		final ITemplateVersion version = inserted.listIterator(inserted.size()).previous();
		final ITemplateVersion result =
		    ((TemplateVersionDataService)getService()).findLastVersion(getSession(), version
		        .getTemplate().getKey());

		Assert.assertNotNull("Result is null", result);
		Assert.assertEquals("Wrong data found", version.getKey(), result.getKey());
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindLastVersionUsingNull() throws Exception {
		Exception exception = null;

		try {
			((TemplateVersionDataService)getService()).findLastVersion(getSession(), null);
		}
		catch (final Exception e) {
			exception = e;
			e.printStackTrace();
		}

		Assert.assertNotNull("Exception thrown", exception);
	}

	/**
	 * Test get instance.
	 */
	@Test
	public final void testGetInstance() {
		Assert.assertEquals("Not a singleton", TemplateVersionDataService.getInstance(),
		    TemplateVersionDataService.getInstance());
	}
}
